
/*数码管的显示是扫描方法显示，扫描间隔由定时器决定（暂为2ms）。在定时器中断处理函数中，每次只驱动1个数码管，下一个中断处理下一个数码管。
定时器ISR，处理的数据是seg_cur.seg[seg_cur.idx].data。所以，只需要更改xxx.seg[idx].data即可。现在没有包装好，很多函数都是直接操作seg_cur.seg[seg_cur.idx].data。
*/
#include <string.h>
#include <stdio.h>

#include "stm32l4xx.h"
#include "stm32l4xx_ll_bus.h"
#include "stm32l4xx_ll_gpio.h"
#include "stm32l4xx_ll_tim.h"

#include "bsp.h"
#include "dbgUart.h"




/*定义DISP_ANA模式下小数点的固定位置。
*/
#define DOT_POS_ANA						3



//数码管的8段电平控制。
#ifdef V11
	#define A_ON							LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_15)
	#define A_OFF							LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_15)
#else
#define A_ON							LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_8)
#define A_OFF							LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_8)
#endif
#define B_LED4_STAB_ON					LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_6)
#define B_LED4_STAB_OFF					LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_6)
#define C_LED5_ON						LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_0)
#define C_LED5_OFF						LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_0)
#define D_ON							LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5)
#define D_OFF							LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5)
#define E_LED3_ZERO_ON					LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_6)
#define E_LED3_ZERO_OFF					LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6)
#define F_ON							LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_7)
#define F_OFF							LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_7)
#ifdef V11
	#define G_ON							LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_3)
	#define G_OFF							LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_3)
#else
	#define G_ON							LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_4)
	#define G_OFF							LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4)
#endif

#define DP_ON							LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_1)
#define DP_OFF							LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_1)


static void seg_sel(uint8_t x);
static void seg_disp(uint8_t data, uint8_t dot);
//static void seg_tim_scan_init(uint32_t T);
static void seg_buf1_to_seg(void);
void seg_sel_none(void);
//static void zeros_deal_in_not_neg(char* str);	//非负数字符串前导零的去除。
//static void zeros_deal_in_neg(char* str);		//负数字符串前导零的去除。
void BUZ_TMO_Handler(void);
void SCAN_TMO_Handler(void);


enum X{X0= 0,X1,X2,X3,X4,X5,X6};				//选通引脚的枚举类型
enum OWNER{OWN_INT=0,OWN_APP};


/*支持1个数码管显示的元素。
*/
typedef struct _SEG{
	uint8_t data;
	uint8_t hasDot;			//是否显示小数点
	uint8_t disp_mode;		//亮，灭，闪
	uint8_t sta;			//仅在闪模式下有效，0---闪下的灭，其他---闪下的亮。
	uint8_t internal;		//闪模式下的设定时长，当计时cnt到达时，更改sta。
	uint8_t res1;
	uint16_t cnt;			//闪模式下的状态计时。
}SEG;

typedef struct _SEG7{
	signed char buf_disp_1[8];			//C 6个数码管和3个发光二极管。小数点占1个字节，但不单独显示。buf_disp_1[0]是3个发光二极管状态。
	signed char buf_disp_2[8];			//C 显示缓存。
	SEG seg[7];							//C !!seg[0]对应发光二极管，seg[1]对应左起第1个数据管，seg[2]对应左起第2个数据管...。3个指示灯（发光二极管）的闪，不属于disp_mode的闪（8段全闪），需要更新数据，不是设置状态。
	uint8_t owner;						//C 拥有者：1--应用，0--显示。当为0时，ISR检测到，更新buf_disp_1[]到seg[]。
	uint8_t idx;						//C 扫描显示过程中的中间状态。
	uint16_t cnt;						//闪模式下的状态计时。
	uint8_t internal;					//闪模式下的设定时长，当计时cnt到达时，更改sta。
	uint8_t sta;						//仅在闪模式下有效，0---闪下的灭，其他---闪下的亮。
}SEG7;

static SEG7 seg_cur={.idx= 0};



/*配置按键输入引脚。
*/
void bsp_key_hal(void)
{
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
	/*
	K1	Pin28/PB2	按键ZERO/ESC/■，低有效
	K2	Pin27/PB1	按键OPTION/▲，低有效
	K3	Pin57/PB5	按键MODE/▷，低有效
	K4	Pin56/PB4	按键HOLD/ENTER/●，低有效
	*/
	LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_2,LL_GPIO_PULL_UP);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_2, LL_GPIO_MODE_INPUT);
	
	LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_1,LL_GPIO_PULL_UP);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_1, LL_GPIO_MODE_INPUT);
	
	LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_5,LL_GPIO_PULL_UP);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_INPUT);
	
	LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_4,LL_GPIO_PULL_UP);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_4, LL_GPIO_MODE_INPUT);
}


/*数码管用到的GPIO:数码管的8段+6个选通引脚
  1个3个发光二极管的选通引脚
*/
void bsp_seg_hal(void)
{
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
	/*
	A	Pin61/PB8	数码管的A段，低有效
	B	Pin58/PB6	数码管的B段和LED4，低有效
	C	Pin14/PA0	数码管的C段和LED5，低有效
	D	Pin21/PA5	数码管的D段，低有效
	E	Pin22/PA6	数码管的E段和LED3，低有效
	F	Pin59/PB7	数码管的F段，低有效
	G	Pin20/PA4	数码管的G段，低有效
	DP	Pin15/PA1	数码管的DP段，低有效
	(没有bit7 6 5 4 3 2 1 0的对应关系）
	*/
	#ifdef V11
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_15,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_15, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_15);
	#else
	LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_8,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_8, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_8);
	#endif
	
	LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_6,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_6, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_6);
	
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_0,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_0);
	
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_5,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5);
	
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_6,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_6, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6);
	
	LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_7,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_7, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_7);
	
	#ifdef V11
	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_3,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_3, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_3);
	#else
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_4,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_4, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);
	#endif
	
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_1,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_1);
	
	/*
	X1	Pin26/PB0	第1个数码管选通，低有效
	X2	Pin25/PC5	第2个数码管选通，低有效
	X3	Pin24/PC4	第3个数码管选通，低有效
	X4	Pin9/PC1	第4个数码管选通，低有效
	X5	Pin3/PC14	第5个数码管选通，低有效
	X6	Pin2/PC13	第6个数码管选通，低有效
	X0	Pin23/PA7	3个发光二极管的选通，低有效
	*/
	LL_GPIO_SetPinOutputType(GPIOB, LL_GPIO_PIN_0,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_0, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_0);	
	
	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_5,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_5);	
	
	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_4,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_4, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_4);	

	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_1,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_1, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_1);
	
	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_14,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_14, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_14);

	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_13,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_13, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_13);
	
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_7,LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_7, LL_GPIO_MODE_OUTPUT);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_7);	
	
	
	/*!!重启进入boot，不修改IO和BLE使能引脚。
	*/
//	/*隔离IO。
//	IN1	Pin37/PC6	当外部有信号时，检测到低电平。
//	OUT1	Pin44/PA11	当输出高时，OUTx表现为ON。
//	OUT2	Pin45/PA12	当输出高时，OUTx表现为ON。
//	*/
//	LL_GPIO_SetPinPull(GPIOC, LL_GPIO_PIN_6,LL_GPIO_PULL_UP);
//	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_6, LL_GPIO_MODE_INPUT);
//	
//	
//	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_11,LL_GPIO_OUTPUT_PUSHPULL);
//	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_11, LL_GPIO_MODE_OUTPUT);
//	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_11);	//!!上电默认输出H，即OUTx为OFF。	
//	
//	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_12,LL_GPIO_OUTPUT_PUSHPULL);
//	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_12, LL_GPIO_MODE_OUTPUT);
//	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_12);	//!!上电默认输出H，即OUTx为OFF。
//	
//	
//	/*BLE使能引脚：PC2/Pin10，低有效。
//	*/
//	LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_2,LL_GPIO_OUTPUT_PUSHPULL);
//	LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_2, LL_GPIO_MODE_OUTPUT);
//	LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_2);	//!!上电默认输出L，使能BLE芯片。
	
	
	/*初始化变量*/
	for(int i= 0; i< 7; i++){
		seg_cur.buf_disp_1[i]= 0;
		seg_cur.buf_disp_2[i]= 0;
		
		seg_cur.seg[i].disp_mode= SEG_LIGHT;
		seg_cur.seg[i].data= '1';
		seg_cur.seg[i].hasDot= 0;
	}
	seg_cur.seg[1].data= '1';
	seg_cur.seg[2].data= '2';
	seg_cur.seg[3].data= '3';
	seg_cur.seg[4].data= '4';
	seg_cur.seg[5].data= '5';
	seg_cur.seg[6].data= '6';
	

	seg_cur.idx= 0;
	seg_cur.owner= OWN_INT;
	
	seg_tim_scan_init(4-1);	//数码管扫描用定时周期为2ms。	//若为8-6，目测闪。最小取4。QQ实测(N-1)是间隔，不是N。
}



/*驱动一个数码管显示的ASCII和自定义图形（如"-","="等）。
1. 支持ASCII码。
2. 支持自定义图形，>0x80。
如果遇到小数点，需要将小数点和之前的符号放在一起。
*/
static void seg_disp(uint8_t data, uint8_t dot)
{
		A_OFF;
		B_LED4_STAB_OFF;
		C_LED5_OFF;
		D_OFF;
		E_LED3_ZERO_OFF;
		F_OFF;
		G_OFF;
		DP_OFF;
	
		if('0' == data){
			A_ON;
			B_LED4_STAB_ON;
			C_LED5_ON;
			D_ON;
			E_LED3_ZERO_ON;
			F_ON;
		}
		else if('1' == data){
			B_LED4_STAB_ON;
			C_LED5_ON;
		}
		else if('2' == data){	
			//ABGED
			A_ON;
			B_LED4_STAB_ON;
			D_ON;
			E_LED3_ZERO_ON;
			G_ON;	
		}
		else if('3' == data){
			//ABCDG
			A_ON;
			B_LED4_STAB_ON;
			C_LED5_ON;
			D_ON;
			G_ON;	
		}
		else if('4' == data){
			//BCFG
			B_LED4_STAB_ON;
			C_LED5_ON;
			F_ON;
			G_ON;	
		}
		else if('5' == data){
			//ACDFG
			A_ON;
			C_LED5_ON;
			D_ON;
			F_ON;
			G_ON;	
		}
		else if('6' == data){
			//ACDEFG
			A_ON;
			C_LED5_ON;
			D_ON;
			E_LED3_ZERO_ON;
			F_ON;
			G_ON;	
		}
		else if('7' == data){
			//ABC
			A_ON;
			B_LED4_STAB_ON;
			C_LED5_ON;
		}
		else if('8' == data){
			//ABCDEFG
			A_ON;
			B_LED4_STAB_ON;
			C_LED5_ON;
			D_ON;
			E_LED3_ZERO_ON;
			F_ON;
			G_ON;	
		}
		else if('9' == data){
			//ABCDFG
			A_ON;
			B_LED4_STAB_ON;
			C_LED5_ON;
			D_ON;
			F_ON;
			G_ON;	
		}
		else{	//自定义图形（!!但都能对应到ASCII中，以方便操作）。
			if(('a' == data) || ('A' == data)){
				////ABCEFG
				A_ON;
				B_LED4_STAB_ON;
				C_LED5_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;	
			}
			else if(('b' == data) || ('B' == data)){
				//CDEFG
				C_LED5_ON;
				D_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			} 
			else if('c' == data){
				//DEG
				D_ON;
				E_LED3_ZERO_ON;
				G_ON;
			}
			else if('C' == data){
				//DEFA
				D_ON;
				E_LED3_ZERO_ON;
				F_ON;
				A_ON;
			}
			else if(('d' == data) || ('D' == data)){
				if('d'== data){
					//BCDEG
					B_LED4_STAB_ON;
					C_LED5_ON;
					D_ON;
					E_LED3_ZERO_ON;
					G_ON;
				}
				else{
					
				}
			}
			else if(('e' == data) || ('E' == data)){
				//ADEFG
				A_ON;
				D_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			}
			else if(('f' == data) || ('F' == data)){
				//AEFG
				A_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			}
			else if(('g' == data) || ('G' == data)){	//9
				//ABCDFG
				A_ON;
				B_LED4_STAB_ON;
				C_LED5_ON;
				D_ON;
				F_ON;
				G_ON;
			}
			else if(('h' == data) || ('H' == data)){
				if('h' == data){
					//
					C_LED5_ON;
					E_LED3_ZERO_ON;
					F_ON;
					G_ON;
				}
				else{
					//
					B_LED4_STAB_ON;
					C_LED5_ON;
					E_LED3_ZERO_ON;
					F_ON;
					G_ON;
				}
			}
			else if(('i' == data) || ('I' == data)){
				if('i' == data){
					C_LED5_ON;
				}
				else{
					E_LED3_ZERO_ON;
					F_ON;
				}
			}
			else if(('j' == data) || ('J' == data)){
				//BCD
				B_LED4_STAB_ON;
				C_LED5_ON;
				D_ON;
			}
			else if(('k' == data) || ('K' == data)){
				//无
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			}
			else if(('l' == data) || ('L' == data)){
				//DEF
				D_ON;
				E_LED3_ZERO_ON;
				F_ON;
			}
			else if(('m' == data) || ('M' == data)){
				//无
			}
			else if(('n' == data) || ('N' == data)){
				if('n' == data){
					//显示'n'
					C_LED5_ON;
					E_LED3_ZERO_ON;
					G_ON;
				}
				else{
					//显示‘N'
					A_ON;
					B_LED4_STAB_ON;
					C_LED5_ON;
					E_LED3_ZERO_ON;
					F_ON;
				}
			}
			else if(('o' == data) || ('O' == data)){
				if('o' == data){
					//CDEG
					C_LED5_ON;
					D_ON;
					E_LED3_ZERO_ON;
					G_ON;
				}
				else{
					//'O'显示一样：'0'
					A_ON;
					B_LED4_STAB_ON;
					C_LED5_ON;
					D_ON;
					E_LED3_ZERO_ON;
					F_ON;
				}
			}
			else if(('p' == data) || ('P' == data)){
				//无
				A_ON;
				B_LED4_STAB_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			}
			else if(('q' == data) || ('Q' == data)){
				//无
				A_ON;
				B_LED4_STAB_ON;
				C_LED5_ON;
				F_ON;
				G_ON;
			}
			else if(('r' == data) || ('R' == data)){
				//参考DT45的显示：Force
				E_LED3_ZERO_ON;
				G_ON;
			}
			else if(('s' == data) || ('S' == data)){
				//显示等于'5'
				//ACDFG
				A_ON;
				C_LED5_ON;
				D_ON;
				F_ON;
				G_ON;
			}
			else if(('t' == data) || ('T' == data)){
				//无
				//ACDFG
				D_ON;
				E_LED3_ZERO_ON;
				F_ON;
				G_ON;
			}
			else if(('u' == data) || ('U' == data)){
				if('u' == data){
					//CDE
					C_LED5_ON;
					D_ON;
					E_LED3_ZERO_ON;
				}
				else{
					//缺AG
					B_LED4_STAB_ON;
					C_LED5_ON;
					D_ON;
					E_LED3_ZERO_ON;
					F_ON;
				}
			}
			else if(('v' == data) || ('V' == data)){
				//无
			}
			else if(('w' == data) || ('W' == data)){
				//无
			}
			else if(('x' == data) || ('X' == data)){
				//无
			}
			else if(('y' == data) || ('Y' == data)){
				//缺ae
				B_LED4_STAB_ON;
				C_LED5_ON;
				D_ON;
				F_ON;
				G_ON;
			}
			else if(('z' == data) || ('Z' == data)){
				//无
			}
			
			//非英文字符
			else if('-' == data){
				G_ON;	
			}
			else if('=' == data){
				D_ON;
				G_ON;
			}
			else if( ' ' == data){
				//空
			}
			else{
				/*非ASCII码，可能对应发光二级管
				bit0---LED3_ZERO
				bit1---LED4_STAB
				bit2---LED5_HOLD
				*/
				if(data & 0x01){
					E_LED3_ZERO_ON;
				}
				if(data & 0x02)
					B_LED4_STAB_ON;
				if(data & 0x04)
					C_LED5_ON;
				
				//uartS("\n\terr:unknow char");
			}
		}
		
		if(0 != dot){
			DP_ON;
		}
}


/*数码管的显示为动态扫描：共7个选通引脚，扫描一次为4*7ms，即定时器周期为4ms（暂定）
输入参数 T: 定时器周期。
使用TIM7.
a. 当ARPE=1，只在event UEV时更新ARR。
b. The update event is sent when the counter reaches the overflow value and if the UDIS bit equals 0 in the TIMx_CR1 register. 
   The counter counts from 0 to the auto-reload value (contents of the TIMx_ARR register), then restarts from 0 and generates a counter overflow event.
*/
void seg_tim_scan_init(uint32_t T)
{
	if(0 == T)
		return;
	
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);
	
	LL_TIM_SetPrescaler(TIM7, 48000-1);	//分频到1KHz。
	LL_TIM_SetAutoReload(TIM7, T);
	
	LL_TIM_GenerateEvent_UPDATE(TIM7);	//马上更新ARR和PSC。
	
	LL_TIM_ClearFlag_UPDATE(TIM7);
	LL_TIM_EnableIT_UPDATE(TIM7);
	
	LL_TIM_EnableCounter(TIM7);
	
	NVIC_SetPriority(TIM7_IRQn, 7);
	NVIC_EnableIRQ(TIM7_IRQn);
}


/*在TIM7的ISR中，更新数码管。
typedef struct _SEG{
	uint8_t data;
	uint8_t hasDot;				//是否显示小数点
	uint8_t disp_mode;			//亮，灭，闪
	uint8_t internal;			//闪的时长
	uint16_t cnt;				//闪或灭的记时。
}SEG;
*/
void SCAN_TMO_Handler(void)
{
	LL_TIM_ClearFlag_UPDATE(TIM7);
	
	//BUZ_ON;
	//DBG_UART->TDR= 'x';
	
	seg_sel_none();	//seg_sel(seg_cur.idx);
	
	
	//要显示seg_cur.idx。
	if(SEG_LIGHT == seg_cur.seg[seg_cur.idx].disp_mode){
		//亮
		seg_disp(seg_cur.seg[seg_cur.idx].data, seg_cur.seg[seg_cur.idx].hasDot);
	}
	else if(SEG_FLASH == seg_cur.seg[seg_cur.idx].disp_mode){
		//闪
		if(seg_cur.sta){
			seg_disp(seg_cur.seg[seg_cur.idx].data, seg_cur.seg[seg_cur.idx].hasDot);
			//uartS("+");
		}
		else{
			seg_disp(' ', 0);	//什么都不显示
			//uartS("-");
		}
	}
	else{ //灭
		seg_disp(' ', 0);		//什么都不显示
	}
	
	seg_sel(seg_cur.idx);		//全灭 ->更新 ->选中，以解决数码管暗闪现象。
	
	
	seg_cur.idx++;
	seg_cur.idx%= 7;

	
	//统一计数，不在单个计数。（暂停）
	if(0 == seg_cur.idx){
		seg_cur.cnt++;
		if(seg_cur.cnt> seg_cur.internal){
			seg_cur.cnt= 0;
			if(seg_cur.sta)
				seg_cur.sta= 0;
			else
				seg_cur.sta= 1;
		}	
	}
	
	//DBG_UART->TDR= 'y';
	//BUZ_OFF;
}


















/*更新SEG结构体的显示内容（只包含6个数码管）。
不处理面板3个指示灯状态。
*/
void seg_updata(char* p)
{
	for(int i= 0; i< 7; i++)
		seg_cur.buf_disp_1[i+1]= p[i];
	
	seg_buf1_to_seg();
}



/*用于测试模式下的全闪控制（含3个发光二极管）。
!!直接修改seg_cur.seg[]。
*/
void seg_flash_all(uint32_t en)
{
	if(en){
		for(int i=0; i<7; i++){
			seg_cur.seg[i].disp_mode= SEG_FLASH;
//			seg_cur.seg[i].cnt= 0;
//			seg_cur.seg[i].internal= 25;
			seg_cur.cnt= 0;
			seg_cur.internal= TMO_FLASH;	//25*14ms。
		}
	}
	else{
		for(int i=0; i<7; i++){
			seg_cur.seg[i].disp_mode= SEG_LIGHT;
		}
	}
}




/*将seg_cur.buf_disp_1[]格式化到seg_cur.seg[]。主要是整理小数点。
说明：
1. seg_cur.buf_disp_1[0]是发光二极管的状态。
2. seg_cur.buf_disp_[1]及之后，为字符串形式，不含小数点。
3. 小数点根据参数中的小数点位置添加。
*/
static void seg_buf1_to_seg(void)
{
	//处理发光二极管状态
	seg_cur.seg[0].data = seg_cur.buf_disp_1[0];	//
//	
//	//处理_disp_1[1]及其之后
//	char str[7];
//	
//	if(seg_cur.buf_disp_1[0] & LED3_ZERO_MASK){
//		seg_cur.seg[0] |= 
//	}
	/*考虑小数点的一种情况：将N+1处小数点写入N。
	如"1.23" ->
	seg_cur.seg[1].data= '1'; seg_cur.seg[1].hasDot= 1;
	seg_cur.seg[2].data= '2'; seg_cur.seg[2].hasDot= 0;
	seg_cur.seg[3].data= '3'; seg_cur.seg[3].hasDot= 0;
	*/
	uint8_t k= 1;
	
	for(int i=1; i<7; i++){	//6个数码管
		seg_cur.seg[i].data= seg_cur.buf_disp_1[k];
		seg_cur.seg[i].hasDot= 0;
		
		if('.' == seg_cur.buf_disp_1[k+1]){
			seg_cur.seg[i].hasDot= 1;
			k++;
		}
			
		k++;
	}	
}



/*
*/
void seg_sel_none(void)
{
	LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_0);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_5);	
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_4);	
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_1);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_14);
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_13);
	LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_7);	
}

/*选通7个引脚中的1个。
*/
static void seg_sel(uint8_t x)
{
	seg_sel_none();
	
	if(X1 == x){
		LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0);
	}
	else if(X2 == x){
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_5);	
	}
	else if(X3 == x){
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_4);	
	}
	else if(X4 == x){
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_1);
	}
	else if(X5 == x){
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_14);
	}
	else if(X6 == x){
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_13);
	}
	else{	//X0---3个发光二极管。
		LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_7);	
	}
}


/*获取隔离输入的所有引脚状态。1--有效，0--无效。
*/
uint32_t io_get(void)
{
	return LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_6)?0:1;
}



void seg_disp_8_dot(void)
{
	/*初始化变量*/
	for(int i= 0; i< 7; i++){
		seg_cur.buf_disp_1[i]= 0;
		seg_cur.buf_disp_2[i]= 0;
		
		seg_cur.seg[i].disp_mode= SEG_LIGHT;
		seg_cur.seg[i].data= '8';
		seg_cur.seg[i].hasDot= 1;
	}
}


void seg_disp_blank(void)
{
	/*初始化变量*/
	for(int i= 0; i< 7; i++){
		seg_cur.buf_disp_1[i]= 0;
		seg_cur.buf_disp_2[i]= 0;
		
		seg_cur.seg[i].disp_mode= SEG_LIGHT;
		seg_cur.seg[i].data= ' ';
		seg_cur.seg[i].hasDot= 0;
	}
}








/************************ END OF FILE ************************/
